home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / gnu / gnulib / fchart / futil.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  10.4 KB  |  457 lines

  1. /* Fchart - futil.c */
  2. /*
  3.  * Gnuplot code
  4.  * Copyright (C) 1986, 1987, 1990   Thomas Williams, Colin Kelley
  5.  *
  6.  * Permission to use, copy, and distribute this software and its
  7.  * documentation for any purpose with or without fee is hereby granted,
  8.  * provided that the above copyright notice appear in all copies and
  9.  * that both that copyright notice and this permission notice appear
  10.  * in supporting documentation.
  11.  *
  12.  * Permission to modify the software is granted, but not the right to
  13.  * distribute the modified code.  Modifications are to be distributed
  14.  * as patches to released version.
  15.  *
  16.  * This software  is provided "as is" without express or implied warranty.
  17.  *
  18.  *
  19.  * AUTHORS
  20.  *
  21.  *   Original Software:
  22.  *     Thomas Williams,  Colin Kelley.
  23.  *
  24.  *   Gnuplot 2.0 additions:
  25.  *       Russell Lang, Dave Kotz, John Campbell.
  26.  *
  27.  *   Fchart changes and additions:
  28.  *       Piotr Filip Sawicki
  29.  *
  30.  * send your comments or suggestions to fs@uwasa.fi
  31.  *
  32.  */
  33. #include <ctype.h>
  34. #include <setjmp.h>
  35. #include <stdio.h>
  36. #include <errno.h>
  37. #include "plot.h"
  38. #include "fchart.h"
  39.  
  40. extern BOOLEAN screen_ok;
  41.     /* TRUE if command just typed; becomes FALSE whenever we
  42.         send some other output to screen.  If FALSE, the command line
  43.         will be echoed to the screen before the ^ error message. */
  44.  
  45. #ifndef vms
  46. #ifndef __ZTC__
  47. extern int errno, sys_nerr;
  48. extern char *sys_errlist[];
  49. #endif
  50. #endif /* vms */
  51.  
  52. extern char input_line[];
  53. extern struct lexical_unit token[];
  54. extern jmp_buf env;    /* from plot.c */
  55.  
  56.  
  57. /*
  58.  * equals() compares string value of token number t_num with str[], and
  59.  *   returns TRUE if they are identical.
  60.  */
  61. equals(t_num, str)
  62. int t_num;
  63. char *str;
  64. {
  65. register int i;
  66.  
  67.     if (!token[t_num].is_token)
  68.         return(FALSE);                /* must be a value--can't be equal */
  69.     for (i = 0; i < token[t_num].length; i++) {
  70.         if (input_line[token[t_num].start_index+i] != str[i])
  71.             return(FALSE);
  72.         }
  73.     /* now return TRUE if at end of str[], FALSE if not */
  74.     return(str[i] == '\0');
  75. }
  76.  
  77.  
  78.  
  79. /*
  80.  * almost_equals() compares string value of token number t_num with str[], and
  81.  *   returns TRUE if they are identical up to the first $ in str[].
  82.  */
  83. almost_equals(t_num, str)
  84. int t_num;
  85. char *str;
  86. {
  87. register int i;
  88. register int after = 0;
  89. register start = token[t_num].start_index;
  90. register length = token[t_num].length;
  91.  
  92.     if (!token[t_num].is_token)
  93.         return(FALSE);                /* must be a value--can't be equal */
  94.     for (i = 0; i < length + after; i++) {
  95.         if (str[i] != input_line[start + i]) {
  96.             if (str[i] != '$')
  97.                 return(FALSE);
  98.             else {
  99.                 after = 1;
  100.                 start--;    /* back up token ptr */
  101.                 }
  102.             }
  103.         }
  104.  
  105.     /* i now beyond end of token string */
  106.  
  107.     return(after || str[i] == '$' || str[i] == '\0');
  108. }
  109.  
  110.  
  111.  
  112. isstring(t_num)
  113. int t_num;
  114. {
  115.     
  116.     return(token[t_num].is_token &&
  117.            (input_line[token[t_num].start_index] == '\'' ||
  118.            input_line[token[t_num].start_index] == '\"'));
  119. }
  120.  
  121.  
  122. isnumber(t_num)
  123. int t_num;
  124. {
  125.     return(!token[t_num].is_token);
  126. }
  127.  
  128.  
  129. /* never used -- why ? 
  130. isletter(t_num)
  131. int t_num;
  132. {
  133.     return(token[t_num].is_token &&
  134.             (isalpha(input_line[token[t_num].start_index])));
  135. }
  136.     */
  137.  
  138.  
  139. /*
  140.  * copy_str() copies the string in token number t_num into str, appending
  141.  *   a null.  No more than MAX_ID_LEN chars are copied.
  142.  *
  143. copy_str(str, t_num)
  144. char str[];
  145. int t_num;
  146. {
  147. register int i = 0;
  148. register int start = token[t_num].start_index;
  149. register int count;
  150.  
  151.     if ((count = token[t_num].length) > MAX_ID_LEN)
  152.         count = MAX_ID_LEN;
  153.     do {
  154.         str[i++] = input_line[start++];
  155.         } while (i != count);
  156.     str[i] = '\0';
  157. }
  158.  *
  159.  */
  160.  
  161. /*
  162.  * quote_str() does the same thing as copy_str, except it ignores the
  163.  *   quotes at both ends.  This seems redundant, but is done for
  164.  *   efficency.
  165.  */
  166. quote_str(str, t_num)
  167. char str[];
  168. int t_num;
  169. {
  170. register int i = 0;
  171. register int start = token[t_num].start_index + 1;
  172. register int count;
  173.  
  174.     if ((count = token[t_num].length - 2) > MAX_LINE_LEN)
  175.         count = MAX_LINE_LEN;
  176.     if (count>0) do {
  177.         str[i++] = input_line[start++];
  178.         } while (i != count);
  179.     str[i] = '\0';
  180. }
  181.  
  182.  
  183. /*
  184.  *    capture() copies into str[] the part of input_line[] which lies between
  185.  *    the begining of token[start] and end of token[end].
  186.  */
  187. capture(str,start,end)
  188. char str[];
  189. int start,end;
  190. {
  191. register int i,e;
  192.  
  193.     e = token[end].start_index + token[end].length;
  194.     for (i = token[start].start_index; i < e && input_line[i] != '\0'; i++)
  195.         *str++ = input_line[i];
  196.     *str = '\0';
  197. }
  198.  
  199.  
  200. /*
  201.  *    m_capture() is similar to capture(), but it mallocs storage for the
  202.  *  string.
  203.  */
  204. m_capture(str,start,end)
  205. char **str;
  206. int start,end;
  207. {
  208.     register int i,e;
  209.     register char *s;
  210.  
  211.     if (*str)        /* previous pointer to malloc'd memory there */
  212.         free(*str);
  213.     e = token[end].start_index + token[end].length;
  214.     *str = alloc((unsigned int)(e - token[start].start_index + 1), "string");
  215.     s = *str;
  216.     for (i = token[start].start_index; i < e && input_line[i] != '\0'; i++)
  217.         *s++ = input_line[i];
  218.     *s = '\0';
  219. }
  220.  
  221. /*
  222.  *    m_quote_capture() is similar to m_capture(), but it removes
  223.  *    quotes from either end if the string.
  224.  */
  225. m_quote_capture(str,start,end)
  226. char **str;
  227. int start,end;
  228. {
  229.     register int i,e;
  230.     register char *s;
  231.  
  232.     if (*str)        /* previous pointer to malloc'd memory there */
  233.         free(*str);
  234.     e = token[end].start_index + token[end].length-1;
  235.     *str = alloc((unsigned int)(e - token[start].start_index + 1), "string");
  236.     s = *str;
  237.     for (i = token[start].start_index + 1; i < e && input_line[i] != '\0'; i++)
  238.         *s++ = input_line[i];
  239.     *s = '\0';
  240. }
  241.  
  242. /* returns pointer to value of token - no checking. Bogus. Outcomented
  243. convert(val_ptr, t_num)
  244. struct value *val_ptr;
  245. int t_num;
  246. {
  247.     *val_ptr = token[t_num].l_val;
  248. }
  249.     */
  250.  
  251.  
  252. /* not used 
  253. disp_value(fp,val)
  254. FILE *fp;
  255. struct value *val;
  256. {
  257.         switch(val->type) {
  258.             case INT:
  259.                 fprintf(fp,"%d",val->v.int_val);
  260.                 break;
  261.             case CMPLX:
  262.                 if (val->v.cmplx_val.imag != 0.0 )
  263.                     fprintf(fp,"{%g, %g}",
  264.                         val->v.cmplx_val.real,val->v.cmplx_val.imag);
  265.                 else
  266.                     fprintf(fp,"%g", val->v.cmplx_val.real);
  267.                 break;
  268.             default:
  269.                 int_error("unknown type in disp_value()",NO_CARET);
  270.         }
  271. }
  272.     */
  273.  
  274. double
  275. real(tok)        /* returns the real part of val */
  276. int tok;
  277. {
  278.     struct value *val = &token[tok].l_val;
  279.     if (!isnumber(tok))
  280.         int_error("number expected",tok);
  281.     switch(val->type) {
  282.         case INT:
  283.             return((double) val->v.int_val);
  284.             break;
  285.         case CMPLX:
  286.             return(val->v.cmplx_val.real);
  287.     }
  288.     int_error("unknown type in real()",NO_CARET);
  289.     /* NOTREACHED */
  290. }
  291.  
  292. /*
  293. struct value *
  294. complex(a,realpart,imagpart)
  295. struct value *a;
  296. double realpart, imagpart;
  297. {
  298.     a->type = CMPLX;
  299.     a->v.cmplx_val.real = realpart;
  300.     a->v.cmplx_val.imag = imagpart;
  301.     return(a);
  302. }
  303.  
  304.  
  305. struct value *
  306. integer(a,i)
  307. struct value *a;
  308. int i;
  309. {
  310.     a->type = INT;
  311.     a->v.int_val = i;
  312.     return(a);
  313. }
  314. */
  315.  
  316.  
  317. os_error(str,t_num)
  318. char str[];
  319. int t_num;
  320. {
  321. #ifdef vms
  322. static status[2] = {1, 0};        /* 1 is count of error msgs */
  323. #endif
  324.  
  325. register int i;
  326.  
  327.     /* reprint line if screen has been written to */
  328.  
  329.     if (t_num != NO_CARET) {        /* put caret under error */
  330.         if (!screen_ok)
  331.             fprintf(stderr,"\n%s%s\n", PROMPT, input_line);
  332.  
  333.         for (i = 0; i < sizeof(PROMPT) - 1; i++)
  334.             (void) putc(' ',stderr);
  335.         for (i = 0; i < token[t_num].start_index; i++) {
  336.             (void) putc((input_line[i] == '\t') ? '\t' : ' ',stderr);
  337.             }
  338.         (void) putc('^',stderr);
  339.         (void) putc('\n',stderr);
  340.     }
  341.  
  342.     for (i = 0; i < sizeof(PROMPT) - 1; i++)
  343.         (void) putc(' ',stderr);
  344.     fprintf(stderr,"%s\n",str);
  345.  
  346.     for (i = 0; i < sizeof(PROMPT) - 1; i++)
  347.         (void) putc(' ',stderr);
  348. #ifdef vms
  349.     status[1] = vaxc$errno;
  350.     sys$putmsg(status);
  351.     (void) putc('\n',stderr);
  352. #else
  353. #ifdef __ZTC__
  354.     fprintf(stderr,"error number %d\n\n",errno);
  355. #else
  356.     if (errno >= sys_nerr)
  357.         fprintf(stderr, "unknown errno %d\n\n", errno);
  358.     else
  359.         fprintf(stderr,"(%s)\n\n",sys_errlist[errno]);
  360. #endif
  361. #endif
  362.  
  363.     longjmp(env, TRUE);    /* bail out to command line */
  364. }
  365.  
  366.  
  367. int_error(str,t_num)
  368. char str[];
  369. int t_num;
  370. {
  371. register int i;
  372.  
  373.     /* reprint line if screen has been written to */
  374.  
  375.     if (t_num != NO_CARET) {        /* put caret under error */
  376.         if (!screen_ok)
  377.             fprintf(stderr,"\n%s%s\n", PROMPT, input_line);
  378.  
  379.         for (i = 0; i < sizeof(PROMPT) - 1; i++)
  380.             (void) putc(' ',stderr);
  381.         for (i = 0; i < token[t_num].start_index; i++) {
  382.             (void) putc((input_line[i] == '\t') ? '\t' : ' ',stderr);
  383.             }
  384.         (void) putc('^',stderr);
  385.         (void) putc('\n',stderr);
  386.     }
  387.  
  388.     for (i = 0; i < sizeof(PROMPT) - 1; i++)
  389.         (void) putc(' ',stderr);
  390.     fprintf(stderr,"%s\n\n",str);
  391.  
  392.     longjmp(env, TRUE);    /* bail out to command line */
  393. }
  394.  
  395.  
  396. check_ranges(v,f)  /* check if two ranges are not overlapping */
  397. struct pair *v, *f;
  398. {
  399.     if (v->from == -1 && (!f || f->from == -1)) return(TRUE);  /* both undefined */
  400.     if (v->from != -1 && v->upto != -1 &&
  401.         v->from > v->upto) return(FALSE);  /* v range is empty */
  402.     if (!f) return(TRUE);  /* only v given, and it's OK */
  403.     if (f->from != -1 && f->upto != -1 &&
  404.         f->from > f->upto) return(FALSE);  /* f range is empty */
  405.     if (v->from == -1 || f->from == -1) return(TRUE);  /* only one defined, and it is OK */
  406.     /* further checking is so boring ... */
  407.     if (v->from < f->from) {  /* v (probably) to the left of f */
  408.         if (v->upto == -1 || v->upto >= f->from) return(FALSE);  /* overl. */
  409.     }
  410.     else if (v->from > f->from) {
  411.         if (f->upto == -1 || f->upto >= v->from) return(FALSE);
  412.     }
  413.     else return(FALSE);  /* both start in the same place */
  414.     return(TRUE);  /* otherwise OK */
  415. }
  416.  
  417.             
  418. /* Lower-case the given string (DFK) */
  419. /* Done in place. */
  420. void lower_case(s)
  421. char *s;
  422. {
  423.     register char *p = s;
  424.     
  425.     while (*p != '\0') {
  426.         if (isupper(*p))
  427.             *p = tolower(*p);
  428.         p++;
  429.     }
  430. }
  431.  
  432. /* Squash spaces in the given string (DFK) */
  433. /* That is, reduce all multiple white-space chars to single spaces */
  434. /* Done in place. */
  435. void squash_spaces(s)
  436. char *s;
  437. {
  438.     register char *r = s;     /* reading point */
  439.     register char *w = s;     /* writing point */
  440.     BOOLEAN space = FALSE;        /* TRUE if we've already copied a space */
  441.     
  442.     for (w = r = s; *r != '\0'; r++) {
  443.         if (isspace(*r)) {
  444.             /* white space; only copy if we haven't just copied a space */
  445.             if (!space) {
  446.                 space = TRUE;
  447.                 *w++ = ' ';
  448.             }               /* else ignore multiple spaces */
  449.         } else {
  450.             /* non-space character; copy it and clear flag */
  451.             *w++ = *r;
  452.             space = FALSE;
  453.         }
  454.     }
  455.     *w = '\0';                /* null terminate string */
  456. }
  457.